/*
#
# Copyright (c) Quaming Intelligent Technology Co., Ltd.
# (C) Copyright 2002-2006 All Rights Reserved.
# 
# SPDX-License-Identifier:	GPL-2.0+
#
*/

#include <common.h>
#include <asm/io.h>

#define BIT_CFG_UPDATE(_a)      (1 << (_a))
#define BIT_SHADOW_EN(_a)       (1 << (_a))
#define BIT_STOP_NOW(_a)        (0x100 << (_a))
#define BIT_OUTPUT_EN(_a)       (1 << (_a))
#define BIT_PWM_CTRL_KEEP       (1 << 0)
#define BIT_PWM_CTRL_STOP_LEVEL_MASK    (0x3 << 0)
#define BIT_PWM_CTRL_STOP_LEVEL (1)

#define MC_PWM_STOP_LEVEL       1

#define MC_REG_PWM_CTRL(_a)     ((_a + 1) * 0x100)
#define MC_REG_PWM_PERD(_a)     ((_a + 1) * 0x100 + 0x4)
#define MC_REG_PWM_DUTY(_a)     ((_a + 1) * 0x100 + 0x8)

#define MC_REG_GLOBAL_CTRL0     (0x0)
#define MC_REG_GLOBAL_CTRL1     (0x4)
#define MC_REG_GLOBAL_CTRL2     (0x8)

int logo_disp_brightness_init(void)
{
    unsigned int reg_base_PWM_GPIO_G1P3_OUT = 0x28200124;
    unsigned int reg_base_PWM = 0x1C000000;
    unsigned int reg_base_PWM_CKG_APB = 0x18000000;
    unsigned int reg_base_PWM_CKG_CFG = 0x19F0028C;
    unsigned int reg_val = 0, reg_tmp = 0;

    reg_val = readl(reg_base_PWM_GPIO_G1P3_OUT);

    /*RGB PWM_LED_BKL Config GPIO7_7 into PWM4_OUT*/
    reg_tmp = ((reg_val & (~3)) | 2);
    writel(reg_tmp, reg_base_PWM_GPIO_G1P3_OUT);

    /*APB PWM apb enable */
    reg_val = readl(reg_base_PWM_CKG_APB);
    reg_tmp = ((reg_val | BIT(19)));
    writel(reg_tmp, reg_base_PWM_CKG_APB);
    reg_val = readl(reg_base_PWM_CKG_APB + 4);
    reg_tmp = ((reg_val | BIT(21)));
    writel(reg_tmp, reg_base_PWM_CKG_APB + 4);

    /*PWM CKG 24MHz, Config PWM CLK SRC */
    reg_val = readl(reg_base_PWM_CKG_CFG);
    reg_tmp = ((reg_val & (~3)) | 0);
    writel(reg_tmp, reg_base_PWM_CKG_CFG);
    /*PWM Global CTRL0, Config PWM4*/
    reg_tmp = readl(reg_base_PWM + MC_REG_GLOBAL_CTRL0);
    writel((BIT(4) | reg_tmp), reg_base_PWM + 0x0000);
    /*PWM Global CTRL1, Config PWM4*/
    writel(0, reg_base_PWM + MC_REG_GLOBAL_CTRL1);
    /*PWM CTRL*/
    writel(0x7, reg_base_PWM + MC_REG_PWM_CTRL(4) + 0x0);
    /*PWN CFG0 period*/
    writel(1200, reg_base_PWM + MC_REG_PWM_CTRL(4) + 0x4);
    /*PWN CFG1 duty*/
    writel(600, reg_base_PWM + MC_REG_PWM_CTRL(4) + 0x8);
    /*PWN CFG2 phase*/
    writel(0x0, reg_base_PWM + MC_REG_PWM_CTRL(4) + 0xC);
    /*PWN CFG3 delay*/
    writel(0x0, reg_base_PWM + MC_REG_PWM_CTRL(4) + 0x10);
    /*PWN CFG4 number*/
    writel(0xFFFFFFFF, reg_base_PWM + MC_REG_PWM_CTRL(4) + 0x14);

    /*PWM Global CTRL2, enable PWM4*/
    writel(BIT(4), reg_base_PWM + MC_REG_GLOBAL_CTRL2);

    return 0;
}

int logo_disp_brightness_set(int brightness)
{
    unsigned int reg_base_PWM = 0x1C000000;
    unsigned int duty, reg;

    duty = (unsigned int)((brightness * 1200) / 256);
	//enable channel config
	reg = readl(reg_base_PWM + MC_REG_GLOBAL_CTRL0);
	reg |= BIT_CFG_UPDATE(4);
	writel(reg, reg_base_PWM + MC_REG_GLOBAL_CTRL0);
	//pulse will stop pulse
	reg = readl(reg_base_PWM + MC_REG_GLOBAL_CTRL1);
	reg |= BIT_STOP_NOW(4);
	writel(reg, reg_base_PWM + MC_REG_GLOBAL_CTRL1);

	reg = BIT_PWM_CTRL_KEEP;
	reg |= (MC_PWM_STOP_LEVEL << BIT_PWM_CTRL_STOP_LEVEL) & BIT_PWM_CTRL_STOP_LEVEL_MASK;
	writel(reg,  reg_base_PWM + MC_REG_PWM_CTRL(4));
	writel(duty, reg_base_PWM + MC_REG_PWM_DUTY(4));
	//stop old pulse
	reg = readl(reg_base_PWM + MC_REG_GLOBAL_CTRL2);
	reg |= BIT_OUTPUT_EN(4);
	writel(reg, reg_base_PWM + MC_REG_GLOBAL_CTRL2);

    return 0;
}

void logo_disp_init_bl(void)
{
    logo_disp_brightness_init();
}

void logo_disp_set_bl(int brightness)
{
    logo_disp_brightness_set(brightness);
}

